<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of BUIScreenFlow2
 *
 * @author Administrator
 */
class BUIScreenFlow extends BUIControl implements Iterator {

    const CONTEXT_VARIABLE_SCREENFLOW_INDEX = 'screenflow_index';

    protected $screens = array();
    protected $index = 0;

    public function __construct($name = NULL) {
        if ($name == NULL)
            $name = strtolower(get_class($this));
        parent::__construct($name);
    }

    public function getIndex() {
        return $this->index;
    }

    public function setIndex($index) {
        if (is_numeric($index) && $index > 0)
            $this->index = $index;
    }

    public function addScreen($screen, $name = NULL) {

        if (is_string($screen)) {
            $name = $screen;
            $screen = new BUIScreen($name);
            $this->screens[$screen->getId()] = $screen;
        }

        if ($screen instanceof BUIScreen)
            $this->screens[$screen->getId()] = $screen;

        if (is_array($screen)) {
            $screenData = $screen;
            $screenClass = 'BUIScreen';
            if (isset($screen['class']))
                $screenClass = $screen['class'];

            if (class_exists($screenClass))
                $screen = new $screenClass();
            else
                $screen = new BUIScreen();

            if ($name != NULL)
                $screen->setName($name);

            $screen->load($screenData);

            $this->screens[$screen->getId()] = $screen;
        }
    }

    public function getScreens() {
        return $this->screens;
    }

    //init screenflow from data
    public function load($data = NULL) {

        if (is_array($data)) {
            $flowConfig = $data;
            $flowName = 'startScreenFlow';
            if (isset($flowConfig['name'])) {
                $flowName = $flowConfig['name'];
                //if (isset($flowConfig['name']))                
            }
            $this->name = $flowName;
            if (isset($flowConfig['views'])) {
                $views = $flowConfig['views'];
                if (is_string($views))
                    $this->addViews($views);
                if (is_array($views)) {
                    foreach ($views as $view)
                        $this->addViews($view);
                }
            }
            if (isset($flowConfig['screens'])) {
                $screens = $flowConfig['screens'];
                foreach ($screens as $name => $screen) {
                    $this->addScreen($screen, $name);
                }
            }
            /*
              if(isset($flowConfig['class']))
              $flowClass = $flowConfig['class'];
              if($flowClass!=NULL && class_exists($flowClass))
              $scnFlow = new $flowClass();
              else
              $scnFlow = new BUIScreenFlow2 ();
             * 
             */
        }

        if ($data instanceof BConfig) {

            $flowConfig = $data;

            $flowName = $flowConfig->getName();

            if ($flowConfig->getConfigValue('name') != null)
                $flowName = $flowConfig->getConfigValue('name');
            /*
              $flowClass = $flowConfig->getConfigValue('class');

              if (is_string($flowClass) && class_exists($flowClass)) {
              $scnFlow = new $flowClass($flowName);
              }
              else
              $scnFlow = new BUIScreenFlow2($flowName);
             * 
             */

            $flowViews = $flowConfig->getConfigValue('views');

            if (is_string($flowViews))
                $this->addViews($flowViews);

            if ($flowViews instanceof BConfig) {
                $views = $flowViews->getConfigList();
                foreach ($views as $viewConfig) {
                    $this->addViews($viewConfig->getValue());
                }
            }

            $screens = $flowConfig->getConfig('screens')->getConfigList();

            foreach ($screens as $screenConfig) {
                $screenClass = $screenConfig->getValue('class');
                if (is_string($screenClass) && class_exists($screenClass)) {
                    $screen = new $screenClass;
                } else {
                    $screen = new BUIScreen();
                }
                $screen->load($screenConfig);
                $this->addScreen($screen);
            }
        }
    }

    public function removeScreen($index = 0) {
        if (is_numeric($index)) {
            $i = 0;
            foreach ($this->screens as $key => $screen) {
                //$i++;
                if ($i == $index)
                    unset($this->screens[$key]);
                $i++;
            }
        }

        if (is_string($index))
            unset($this->screens[$index]);
    }

    public function addContextVariable($name, $value, $scope = NULL, $type = NULL) {
        $tObj = Blyn::app()->getContextObj();

        $tObj->addContextVariable(BContextObj::Scope_ScreenFlow, $name, $value);

        //Blyn::app()->setContextObj($tObj);
    }

    public function getContextVariable($name, $scope = NULL, $type = NULL) {
        $tObj = Blyn::app()->getContextObj();
        return $tObj->getContextVariable(BContextObj::Scope_ScreenFlow, $name);
    }

    public function resetContextVariable($name = NULL) {
        $tObj = Blyn::app()->getContextObj();
        /**
         * for scope reset, only happen when id changed
         */
        if ($name == NULL) {
            $tId = $this->getContextVariable(BContextObj::Current_Id);
            $myId = $this->getId();
            if ($tId != $myId) {
                $tObj->resetContextVariable(BContextObj::Scope_ScreenFlow);
                //$tObj->resetContextVariable(BContextObj::Scope_AppMeta, BContextObj::V_CurrentScreenFlowId);
                //$tObj->resetContextVariable(BContextObj::Scope_AppMeta, BContextObj::V_CurrentScreenFlowClass);
                $this->addContextVariable(BContextObj::Current_Id, $myId);
            }
        } else {
            //reset name can alway do   
            /*
              if (name == BContextObj::VariableName_Id)
              return $tObj->resetContextVariable(BContextObj::Scope_AppMeta, BContextObj::V_CurrentScreenFlowId);
              if (name == BContextObj::VariableName_Class)
              return $tObj->resetContextVariable(BContextObj::Scope_AppMeta, BContextObj::V_CurrentScreenFlowClass);
             * 
             */
            $tObj->resetContextVariable(BContextObj::Scope_ScreenFlow, $name);
        }
    }

    //return current screen
    public function current() {

        if (is_numeric($this->index)) {
            $i = 0;
            foreach ($this->screens as $screen) {
                if ($i == $this->index)
                    return $screen;
                $i++;
            }
        }

        //by default,return first screen
        return reset($this->screens);
    }

    public function key() {
        return $this->getIndex();
    }

    public function next() {
        if (is_numeric($this->index))
            $this->index++;
        if ($this->index > count($this->screens))
            $this->index = count($this->screens);
    }

    public function rewind() {
        $this->index = 0;
    }

    public function valid() {
        $screen = $this->current();
        if ($screen instanceof BUIScreen2)
            return TRUE;
        return FALSE;
    }

    public function getAjaxContainerId($data = null) {
        //parent::getAjaxContainerId($data);
        return BUIBase::ajaxContainter_screenFlow;
    }

    public function getAjaxLink($name, $data = NULL, $sender = NULL, $router = 'site/index', $updateControl = NULL) {
        if ($this->getNode() != NULL && Blyn::app()->getCurrentNode()->getId() != $this->getNode()->getId())
            return $this->getNode()->getAjaxLink($name, $data, $sender, $router, $updateControl);
        else {
            if ($updateControl == NULL)
                $updateControl = Blyn::app()->getCurrentNode()->getUIManager();
            return parent::getAjaxLink($name, $data, $sender, $router, $updateControl);
        }
        //return parent::createAjaxLink($name, $this->getUrl(), BUIBase::ajaxContainter_Space, Blyn::app()->getActiveSpace()->getUIManager()->getLayoutView(), $data);
    }

    public function onRender($data = null) {

        $flowIndex = $this->getContextVariable(BUIScreenFlow::CONTEXT_VARIABLE_SCREENFLOW_INDEX);
        if (is_numeric($flowIndex) && $flowIndex > 0)
            $this->setIndex($flowIndex);

        $uiNode = Blyn::app()->getCurrentNode()->getUIManager();
        $uiNode->setCurrentScreenFlow($this);

        //$this->addRenderView('screeflowLayout', $this->getLayoutView(), array('uiObj' => $this));
        //   $this->gotoScreenByIndex($this->index);
        //add controls

        if (Blyn::app()->getUIManager()->getCurrentScreen() != NULL) {
            $uiScreen = Blyn::app()->getUIManager()->getCurrentScreen();
        } else {
            $uiScreen = new BUIScreen();
        }
        $this->addControl($uiScreen, 'activeScreen');
    }

   

//put your code here
}

?>
